#include <sxOpenGL_DefaultBezierCurveRenderer.h>
#include <gl/glut.h>

Sx::OpenGL::Graphics::Objects::Rendering::OpenGL_DefaultBezierCurveRenderer::OpenGL_DefaultBezierCurveRenderer(const std::shared_ptr<OpenGL_Context>& graphicsContext) : 
	GraphicsObjectRenderer(graphicsContext) {}

Sx::OpenGL::Graphics::Objects::Rendering::OpenGL_DefaultBezierCurveRenderer::~OpenGL_DefaultBezierCurveRenderer() {}

bool Sx::OpenGL::Graphics::Objects::Rendering::OpenGL_DefaultBezierCurveRenderer::construct(OpenGL_Context* const graphicsContext, BezierCurve* const curve, StaticRepresentation* const physicalRepresentation) {
	return true;
}

void Sx::OpenGL::Graphics::Objects::Rendering::OpenGL_DefaultBezierCurveRenderer::update(OpenGL_Context* const graphicsContext, BezierCurve* const curve, float dt) {
	return;
}

void Sx::OpenGL::Graphics::Objects::Rendering::OpenGL_DefaultBezierCurveRenderer::render(OpenGL_Context* const graphicsContext, BezierCurve* const curve, StaticRepresentation* const physicalRepresentation) {
	
	glDisable(GL_DEPTH_TEST);
	glPushMatrix();
		glMultMatrixf(curve->transformation().toMatrix4f().data());
		//glPointSize(2.0f);
		/*
		glBegin(GL_POINTS);
			glColor3f(0.0f, 1.0f, 0.0f);
			for ( unsigned int i = 0; i < physicalRepresentation->vertices.size(); i++ ) {
				glVertex3fv(physicalRepresentation->vertices[i].data());
			}
		glEnd();
		*/

		glBegin(GL_LINES);
			if ( (curve->isOneToOneFunction() == false || curve->hasLoop()) && (curve->isEndPointSelected(false) || curve->isEndPointSelected(true)) ) glColor3f(1.0f, 0.0f, 0.0f);
			else if ( curve->isOneToOneFunction() == false || curve->hasLoop() ) glColor3f(0.7f, 0.0f, 0.0f);
			else if ( curve->isEndPointSelected(false) || curve->isEndPointSelected(true) || curve->isControlPointSelected(false) || curve->isControlPointSelected(true ) ) glColor3f(0.4f, 0.6f, 1.0f);
			else if ( curve->isOneToOneFunction() == true ) glColor3f(0.2f, 0.4f, 0.8f);
			else glColor3f(0.2f, 0.4f, 0.8f);

			unsigned int index = 0;
			for ( unsigned int i = 0; i < physicalRepresentation->vertices.size() - 1; i++ ) {
				glVertex3fv(physicalRepresentation->vertices[index].data());
				glVertex3fv(physicalRepresentation->vertices[index+1].data());
				index++;
			}

			if ( curve->isControlPointSelected(false) == true ) glColor3f(1.0f, 1.0f, 1.0f);
			else glColor3f(0.5f, 0.5f, 0.5f);
			glVertex3fv(curve->getEndPoint(false).getPosition().data());
			glVertex3fv(curve->getControlPoint(false).getPosition().data());

			if ( curve->isControlPointSelected(true) == true ) glColor3f(1.0f, 1.0f, 1.0f);
			else glColor3f(0.5f, 0.5f, 0.5f);
			glVertex3fv(curve->getEndPoint(true).getPosition().data());
			glVertex3fv(curve->getControlPoint(true).getPosition().data());
		glEnd();
	
		glPointSize(8.0f);
		glBegin(GL_POINTS);
			if ( (curve->hasLoop() || !curve->isOneToOneFunction()) && curve->isEndPointSelected(false) == true ) glColor3f(1.0f, 0.0f, 0.0f);
			else if ( curve->hasLoop() || !curve->isOneToOneFunction() ) glColor3f(0.7f, 0.0f, 0.0f);
			else if ( curve->isEndPointSelected(false) == true ) glColor3f(0.5f, 0.7f, 1.0f);
			else glColor3f(0.3f, 0.5f, 0.8f);
			glVertex3fv(curve->getEndPoint(false).getPosition().data());

			if ( (curve->hasLoop() || !curve->isOneToOneFunction()) && curve->isEndPointSelected(true) == true ) glColor3f(1.0f, 0.0f, 0.0f);
			else if ( curve->hasLoop() || !curve->isOneToOneFunction() ) glColor3f(0.7f, 0.0f, 0.0f);
			else if ( curve->isEndPointSelected(true) == true ) glColor3f(0.5f, 0.7f, 1.0f);
			else glColor3f(0.3f, 0.5f, 0.8f);
			glVertex3fv(curve->getEndPoint(true).getPosition().data());
			
			

			if ( curve->isControlPointSelected(false) == true ) glColor3f(0.9f, 0.9f, 0.9f);
			else glColor3f(0.8f, 0.8f, 0.8f);
			glVertex3fv(curve->getControlPoint(false).getPosition().data());

			if ( curve->isControlPointSelected(true) == true ) glColor3f(0.9f, 0.9f, 0.9f);
			else glColor3f(0.8f, 0.8f, 0.8f);
			glVertex3fv(curve->getControlPoint(true).getPosition().data());
			
		glEnd();
		
	glPopMatrix();
	glEnable(GL_DEPTH_TEST); 
}
